8051 Microcontroller
Assembly Language Program (ALP) for 8051 Microcontroller
Chapters
Table of Content
Addition of two 8-bit numbers
1ORG 0H ; Start at address 02
3; Define some variables4NUM1 equ 30H5NUM2 equ 31H6SUM equ 32H7
8; Main program loop9MAIN:10 ; Load the first number into the accumulator11 MOV A, NUM112
13 ; Add the second number to the accumulator14 ADD A, NUM215
16 ; Store the result in the sum variable17 MOV SUM, A18
19 ; Loop indefinitely20 SJMP MAIN21
22END ; End of program
This program defines some variables for the two input numbers and the sum, and then enters a main program loop. The program loads the first number into the accumulator, adds the second number to the accumulator, and stores the result in the sum variable. The program then loops indefinitely, allowing the addition to be repeated as needed.
Note that in this example program, the input numbers are assumed to be already loaded into memory at the appropriate addresses (NUM1 and NUM2). In a real-world application, the input numbers would likely be obtained from an external source such as user input or a sensor, and loaded into memory before the addition operation is performed.
Subtraction of two 8-bit numbers
1ORG 0H ; Start at address 02
3; Define some variables4NUM1 equ 30H5NUM2 equ 31H6DIFF equ 32H7
8; Main program loop9MAIN:10 ; Load the first number into the accumulator11 MOV A, NUM112
13 ; Subtract the second number from the accumulator14 SUBB A, NUM215
16 ; Store the result in the difference variable17 MOV DIFF, A18
19 ; Loop indefinitely20 SJMP MAIN21
22END ; End of program
This program defines some variables for the two input numbers and the difference, and then enters a main program loop. The program loads the first number into the accumulator, subtracts the second number from the accumulator using the SUBB (subtract with borrow) instruction, and stores the result in the difference variable. The program then loops indefinitely, allowing the subtraction to be repeated as needed.
Note that in this example program, the input numbers are assumed to be already loaded into memory at the appropriate addresses (NUM1 and NUM2). In a real-world application, the input numbers would likely be obtained from an external source such as user input or a sensor, and loaded into memory before the subtraction operation is performed.
Multiplication of two 8-bit numbers
1ORG 0H ; Start at address 02
3; Define some variables4NUM1 equ 30H5NUM2 equ 31H6RESULT_LOW equ 32H7RESULT_HIGH equ 33H8
9; Main program loop10MAIN:11 ; Load the first number into the accumulator12 MOV A, NUM113
14 ; Multiply the second number by the accumulator15 MUL AB16
17 ; Store the result in the low and high bytes of the result variable18 MOV RESULT_LOW, A19 MOV RESULT_HIGH, B20
21 ; Loop indefinitely22 SJMP MAIN23
24END ; End of program
This program defines some variables for the two input numbers and the result, and then enters a main program loop. The program loads the first number into the accumulator, multiplies the second number by the accumulator using the MUL instruction, and stores the result in the low and high bytes of the result variable. The program then loops indefinitely, allowing the multiplication to be repeated as needed.
Note that in this example program, the input numbers are assumed to be already loaded into memory at the appropriate addresses (NUM1 and NUM2). In a real-world application, the input numbers would likely be obtained from an external source such as user input or a sensor, and loaded into memory before the multiplication operation is performed. Also note that the MUL instruction multiplies the accumulator by the B register, so it is important to load the first number into the accumulator and the second number into the B register before using the MUL instruction.
Division of two 8-bit numbers
1ORG 0H ; Start at address 02
3; Define some variables4NUM1 equ 30H5NUM2 equ 31H6QUOTIENT equ 32H7REMAINDER equ 33H8
9; Main program loop10MAIN:11 ; Load the first number into the accumulator12 MOV A, NUM113
14 ; Divide the accumulator by the second number15 DIV AB16
17 ; Store the quotient and remainder in the appropriate variables18 MOV QUOTIENT, A19 MOV REMAINDER, B20
21 ; Loop indefinitely22 SJMP MAIN23
24END ; End of program
This program defines some variables for the two input numbers and the quotient and remainder, and then enters a main program loop. The program loads the first number into the accumulator, divides the accumulator by the second number using the DIV instruction, and stores the quotient and remainder in the appropriate variables. The program then loops indefinitely, allowing the division to be repeated as needed.
Note that in this example program, the input numbers are assumed to be already loaded into memory at the appropriate addresses (NUM1 and NUM2). In a real-world application, the input numbers would likely be obtained from an external source such as user input or a sensor, and loaded into memory before the division operation is performed. Also note that the DIV instruction divides the accumulator by the B register, and stores the quotient in the accumulator and the remainder in the B register. Therefore, it is important to load the first number into the accumulator and the second number into the B register before using the DIV instruction.
Addition of two 16-bit numbers
1ORG 0H ; Start at address 02
3; Define some variables4NUM1_L equ 30H5NUM1_H equ 31H6NUM2_L equ 32H7NUM2_H equ 33H8SUM_L equ 34H9SUM_H equ 35H10
11; Main program loop12MAIN:13 ; Load the low byte of the first number into the accumulator14 MOV A, NUM1_L15
16 ; Add the low byte of the second number to the accumulator17 ADD A, NUM2_L18
19 ; Store the low byte of the sum in the appropriate variable20 MOV SUM_L, A21
22 ; Load the high byte of the first number into the accumulator23 MOV A, NUM1_H24
25 ; Add the carry flag (if any) to the high byte of the first number26 ADDC A, NUM2_H27
28 ; Store the high byte of the sum in the appropriate variable29 MOV SUM_H, A30
31 ; Loop indefinitely32 SJMP MAIN33
34END ; End of program
This program defines some variables for the two input numbers and the sum, and then enters a main program loop. The program loads the low byte of the first number into the accumulator, adds the low byte of the second number to the accumulator using the ADD instruction, and stores the low byte of the sum in the appropriate variable. The program then loads the high byte of the first number into the accumulator, adds the carry flag (if any) to the high byte of the first number using the ADDC (add with carry) instruction, and stores the high byte of the sum in the appropriate variable. The program then loops indefinitely, allowing the addition to be repeated as needed.
Note that in this example program, the input numbers are assumed to be already loaded into memory at the appropriate addresses (NUM1_L, NUM1_H, NUM2_L, and NUM2_H). In a real-world application, the input numbers would likely be obtained from an external source such as user input or a sensor, and loaded into memory before the addition operation is performed. Also note that since this program adds two 16-bit numbers, it uses the ADDC instruction to handle the carry from the low byte addition to the high byte addition.
Subtraction of two 16-bit numbers
1ORG 0H ; Start at address 02
3; Define some variables4NUM1_L equ 30H5NUM1_H equ 31H6NUM2_L equ 32H7NUM2_H equ 33H8DIFF_L equ 34H9DIFF_H equ 35H10
11; Main program loop12MAIN:13 ; Load the low byte of the first number into the accumulator14 MOV A, NUM1_L15
16 ; Subtract the low byte of the second number from the accumulator17 SUBB A, NUM2_L18
19 ; Store the low byte of the difference in the appropriate variable20 MOV DIFF_L, A21
22 ; Load the high byte of the first number into the accumulator23 MOV A, NUM1_H24
25 ; Subtract the borrow flag (if any) from the high byte of the first number26 SUBB A, NUM2_H27
28 ; Store the high byte of the difference in the appropriate variable29 MOV DIFF_H, A30
31 ; Loop indefinitely32 SJMP MAIN33
34END ; End of program
This program defines some variables for the two input numbers and the difference, and then enters a main program loop. The program loads the low byte of the first number into the accumulator, subtracts the low byte of the second number from the accumulator using the SUBB (subtract with borrow) instruction, and stores the low byte of the difference in the appropriate variable. The program then loads the high byte of the first number into the accumulator, subtracts the borrow flag (if any) from the high byte of the first number using the SUBB instruction, and stores the high byte of the difference in the appropriate variable. The program then loops indefinitely, allowing the subtraction to be repeated as needed.
Note that in this example program, the input numbers are assumed to be already loaded into memory at the appropriate addresses (NUM1_L, NUM1_H, NUM2_L, and NUM2_H). In a real-world application, the input numbers would likely be obtained from an external source such as user input or a sensor, and loaded into memory before the subtraction operation is performed. Also note that since this program subtracts two 16-bit numbers, it uses the SUBB instruction to handle the borrow from the low byte subtraction to the high byte subtraction.
Loop 20 times
1ORG 0H ; start at address 02
3MOV R0, #20 ; initialize loop counter to 204
5Loop: ; start of loop6
7; your loop code goes here8; this code will be executed 20 times9
10DJNZ R0, Loop ; decrement R0 and jump to Loop if it's not zero11
12END ; end of program
In this program, the loop counter is stored in the R0 register and initialized to 20. The program then enters a loop that will execute 20 times. Within the loop, you can include whatever code you want to execute repeatedly. The DJNZ (Decrement and Jump if Not Zero) instruction is used to decrement the loop counter and jump back to the start of the loop if the counter is not zero. When the loop counter reaches zero, the program exits the loop and ends.
Complement value of Accumulator 700 times
1ORG 0H ; start at address 02
3MOV R0, #700 ; initialize loop counter to 7004
5MOV A, your_value ; load your value to the accumulator6
7Loop: ; start of loop8
9CPL A ; complement the value in the accumulator10
11DJNZ R0, Loop ; decrement R0 and jump to Loop if it's not zero12
13END ; end of program
In this program, the loop counter is stored in the R0 register and initialized to 700. The program then enters a loop that will execute 700 times. The value to be complemented is loaded into the accumulator using the MOV instruction. Within the loop, the CPL instruction is used to complement the value in the accumulator. The DJNZ (Decrement and Jump if Not Zero) instruction is used to decrement the loop counter and jump back to the start of the loop if the counter is not zero. When the loop counter reaches zero, the program exits the loop and ends.
Create a table of 2
1ORG 0H ; start at address 02
3MOV R0, #0 ; initialize loop counter to 04MOV R1, #2 ; initialize multiplier to 25
6Loop: ; start of loop7
8MOV A, R1 ; move the value of the multiplier into the accumulator9MOV B, R0 ; move the value of the loop counter into register B10MUL AB ; multiply A and B and store the result in ACC11
12; Store the result in memory. You can choose a memory location that suits your needs.13MOV your_table_location, A14
15INC R0 ; increment the loop counter16DJNZ R1, Loop ; decrement R1 and jump to Loop if it's not zero17
18END ; end of program
In this program, the loop counter is stored in the R0 register and initialized to 0. The multiplier is stored in the R1 register and initialized to 2. The program then enters a loop that will execute as many times as the value in R1. Within the loop, the values of R0 and R1 are multiplied using the MUL instruction, and the result is stored in the ACC register. The result is then stored in memory location of your choice using the MOV instruction. Finally, the loop counter is incremented using the INC instruction, and the loop is repeated until R1 reaches zero. When the loop counter reaches zero, the program exits the loop and ends. You’ll need to replace your_table_location with the memory location where you want to store the table of 2.
Generate the square of a number
1ORG 0H ; start at address 02
3MOV A, your_number ; load the number to be squared into the accumulator4MOV B, A ; copy accumulator to base register5MUL AB ; multiply the accumulator by base register and store the result in ACC6
7; Store the result in memory. You can choose a memory location that suits your needs.8MOV your_result_location, A9
10END ; end of program
In this program, the number to be squared is loaded into the accumulator using the MOV instruction. The MUL instruction is then used to multiply the accumulator by itself, effectively squaring the number. The result is stored in the ACC register, and then stored in memory location of your choice using the MOV instruction. Finally, the program ends. You’ll need to replace your_number with the memory location where your number is stored, and your_result_location with the memory location where you want to store the result.
Square of a number using a look-up table
1ORG 0H ; start at address 02
3MOV A, your_number ; load the number to be squared into the accumulator4MOV DPTR, #LUT ; load the address of the look-up table into the data pointer5
6; Perform a table look-up to find the square of the number.7; The square of the number is stored in the look-up table at the offset that corresponds to the number itself.8; For example, the square of 5 is stored in the look-up table at offset 5.9; After the look-up, the result is stored in the ACC register.10MOV A, @A+DPTR11
12; Store the result in memory. You can choose a memory location that suits your needs.13MOV your_result_location, A14
15END ; end of program16
17LUT: ; start of look-up table18DB 00H ; offset 0 (not used)19DB 01H ; offset 1 (1^2 = 1)20DB 04H ; offset 2 (2^2 = 4)21DB 09H ; offset 3 (3^2 = 9)22DB 10H ; offset 4 (4^2 = 16)23DB 19H ; offset 5 (5^2 = 25)24DB 24H ; offset 6 (6^2 = 36)25DB 31H ; offset 7 (7^2 = 49)26DB 40H ; offset 8 (8^2 = 64)27DB 51H ; offset 9 (9^2 = 81)28DB 64H ; offset 10 (10^2 = 100)29; and so on...
In this program, the number to be squared is loaded into the accumulator using the MOV instruction. The data pointer is then loaded with the address of the look-up table using the MOV DPTR, #LUT instruction. The look-up table contains pre-calculated squares of numbers from 0 to 255, with each square stored at an offset that corresponds to the number itself. The program performs a table look-up to find the square of the number, by adding the accumulator to the address in the data pointer, and then dereferencing that address using the @ operator. The result of the table look-up is stored in the ACC register, and then stored in memory location of your choice using the MOV instruction. Finally, the program ends. You’ll need to replace your_number with the memory location where your number is stored, and your_result_location with the memory location where you want to store the result. Note that the look-up table in this example only goes up to the square of 10, but you can extend it to cover a larger range of numbers if needed.
Generate a delay of 250 microseconds using Timer 0 in Mode 1
1ORG 0H ; start at address 02
3MOV TMOD, #01H ; set Timer 0 to Mode 1 (16-bit timer mode)4MOV TH0, #0F4H ; set the timer to count up to 250 microseconds5MOV TL0, #0H ; clear the lower byte of the timer6
7SETB TR0 ; start Timer 08DELAY: JNB TF0, DELAY ; wait for the timer to overflow (TF0 = 1)9
10CLR TF0 ; clear the timer overflow flag (TF0 = 0)11CLR TR0 ; stop Timer 012END ; end of program
In this program, we start by setting Timer 0 to Mode 1 using the MOV instruction. This sets the timer to operate in 16-bit mode, where the timer counts up from 0 to a maximum value specified by the values in TH0 and TL0 registers. We set TH0 to 0xF4 and TL0 to 0x00, which will cause the timer to count up to 250 microseconds before overflowing.
We then start Timer 0 using the SETB TR0 instruction. This will cause the timer to start counting up. We enter a delay loop that waits for the timer to overflow by checking the TF0 flag using the JNB instruction. When the timer overflows, the TF0 flag is set to 1. We then clear the TF0 flag using the CLR instruction and decrement the R1 register using the DJNZ instruction. This loop continues until R1 is decremented to 0. The number of times R1 is decremented can be adjusted to achieve the desired delay time.
Finally, we stop Timer 0 using the CLR TR0 instruction and end the program.
Note that the delay time achieved by this program is approximate, as it depends on the clock frequency of the microcontroller and the number of instructions executed in the delay loop. To achieve more precise delays, hardware timers or external oscillators can be used.
Generate a square wave of 20kHz on pin P1.5 using Timer 0 in Mode 1
1ORG 0H ; start at address 02
3MOV TMOD, #01H ; set Timer 0 to Mode 1 (16-bit timer mode)4LOOP: MOV TH0, #0F3H ; set the timer to count up to 50 microseconds5 MOV TL0, #0H ; clear the lower byte of the timer6 SETB TR0 ; start Timer 07 SETB P1.5 ; set P1.5 high8HERE: JNB TF0, HERE ; wait for the timer to overflow (TF0 = 1)9 CPL P1.5 ; toggle P1.5 output10 CLR TF0 ; clear the timer overflow flag (TF0 = 0)11 CLR TR012 SJMP LOOP ; loop back to LOOP13
14END ; end of program
In this program, we start by setting Timer 0 to Mode 1 using the MOV instruction. This sets the timer to operate in 16-bit mode, where the timer counts up from 0 to a maximum value specified by the values in TH0 and TL0 registers. We set TH0 to 0xF3 and TL0 to 0x00, which will cause the timer to count up to 50 microseconds before overflowing.
We then start Timer 0 using the SETB TR0 instruction. This will cause the timer to start counting up. We also set P1.5 high using the SETB instruction to initialize the output.
We enter a main loop that waits for the timer to overflow by checking the TF0 flag using the JNB instruction. When the timer overflows, the TF0 flag is set to 1. We then clear the TF0 flag using the CLR instruction, toggle the P1.5 output using the CPL instruction, and loop back to the beginning of the loop using the SJMP instruction.
This loop will toggle the P1.5 output pin every time the timer overflows, which will generate a square wave with a frequency of approximately 20kHz. The exact frequency will depend on the clock frequency of the microcontroller and the number of instructions executed in the main loop.